﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using BrainTechLLC.ThreadSafeObjects;
using System.Collections.Generic;
using System.Threading;

namespace BrainTechLLC.Silverlight.Controls
{
    public class DataVisualizerRegistry
    {
        private static DataVisualizerRegistry _instance;

        public event EventHandler<ObjectEventArgsNonRef<double>> HeightChanged;

        public void OnHeightChanged(double newHeight)
        {
            if (HeightChanged != null)
                HeightChanged(this, new ObjectEventArgsNonRef<double>(newHeight));
        }

        public static DataVisualizerRegistry Instance
        {
            get
            {
                if (_instance == null)
                    Interlocked.CompareExchange<DataVisualizerRegistry>(ref _instance, new DataVisualizerRegistry(), null);

                return _instance;
            }
        }

        public ThreadSafeListAndLookup<Type, DataVisualizerInfo> CollectionVisualizers = new ThreadSafeListAndLookup<Type, DataVisualizerInfo>();
        public ThreadSafeListAndLookup<Type, DataVisualizerInfo> SingleItemVisualizers = new ThreadSafeListAndLookup<Type, DataVisualizerInfo>();
        public ThreadSafeList<DataVisualizerInfo> AllVisualizers = new ThreadSafeList<DataVisualizerInfo>();

        public void RegisterVisualizer(DataVisualizerInfo info)
        {
            if (info.CollectionVisualizer)
                RegisterCollectionVisualizer(info);
            else
                RegisterSingleItemVisualizer(info);
        }

        private void RegisterCollectionVisualizer(DataVisualizerInfo info)
        {
            CollectionVisualizers.Add(info.VisualizeType, info);
            AllVisualizers.Add(info);
        }

        private void RegisterSingleItemVisualizer(DataVisualizerInfo info)
        {
            SingleItemVisualizers.Add(info.VisualizeType, info);
            AllVisualizers.Add(info);
        }

        public DataVisualizerInfo FindVisualizer(Type t, string name, bool isCollection)
        {
            return (isCollection) ? FindCollectionVisualizer(t, name) : FindSingleItemVisualizer(t, name);
        }

        public DataVisualizerInfo FindCollectionVisualizer(Type t, string name)
        {
            if (t == null)
                return null;

            DataVisualizerInfo vis = FindInList(CollectionVisualizers.Find(t), name);

            if (vis == null)
                vis = FindVisualizerInList(t, name);

            return vis;
        }

        private DataVisualizerInfo FindInList(List<DataVisualizerInfo> list, string name)
        {
            if (list == null)
                return null;

            if (string.IsNullOrEmpty(name) && list.Count > 0)
                return list[0];

            for (int n = 0; n < list.Count; n++)
            {
                if (list[n].VisualizerName.Equals(name, StringComparison.OrdinalIgnoreCase))
                    return list[n];
            }

            return null;
        }

        public DataVisualizerInfo FindVisualizerInList(Type t, string name)
        {
            var v = AllVisualizers.Find((vis) => vis.VisualizerName.Equals(name, StringComparison.OrdinalIgnoreCase) && vis.VisualizeType.IsAssignableFrom(t));
            return v;
        }

        public List<DataVisualizerInfo> FindVisualizersForType(Type t, bool isCollection)
        {
            List<DataVisualizerInfo> results = new List<DataVisualizerInfo>();
            var all = AllVisualizers.AllItems;
            for (int n = 0; n < all.Count; n++)
            {
                var vis = all[n];
                if (vis.VisualizeType.IsAssignableFrom(t) && vis.CollectionVisualizer == isCollection)
                    results.Add(vis);
            }
            return results;
        }

        public DataVisualizerInfo FindSingleItemVisualizer(Type t, string name)
        {
            if (t != null)
            {
                DataVisualizerInfo vis = FindInList(SingleItemVisualizers.Find(t), name);

                if (vis == null)
                    vis = FindVisualizerInList(t, name);

                return vis;
            }

            return null;
        }
    }
}
